package cn.hchaojie.camp.day13;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

// 创建一个服务器，接收客户端请求
// ServerSocket
// 实现：能同时接收多个客户端的连接


public class ServerFx extends Application {
	private TextArea ta;
	public static void main(String[] args) {
		launch(args);
	}

	@Override
	public void start(Stage primaryStage) throws Exception {
		VBox box = new VBox(10);
		box.setPadding(new Insets(10));
		
		// 多行输入框
		ta = new TextArea();
		VBox.setVgrow(ta, Priority.ALWAYS);
		box.getChildren().add(ta);
		
		Scene scene = new Scene(box, 500, 300);
		primaryStage.setScene(scene);
		primaryStage.show();
		
		// 必须要创建异步线程去打开socket，否则server.accept()会阻塞ui线程，程序界面就会没有响应
		new Thread(() -> {
			openSocket();	
		}).start();
	}
	
	// 将消息添加到文本框
	public void appendMessage(String message) {
		ta.appendText(message + "\n");
	}

	private void openSocket() {
		// 端口不能用1024端口以下的
		ServerSocket server = null;
		try {
			server = new ServerSocket(6666);
			
			System.out.println("服务器启动了，准备接收连接。。。");
			
			// 接收一个客户端连接
			// 如果有客户端连接，accept会马上返回一个socket对象
			// 如果没有，accept方法会让当前的线程处于阻塞状态
			while (true) {
				Socket socket = server.accept();	// socket代表连接上的客户端
				System.out.println("连上了一个客户端：" + socket.getInetAddress() + " 端口：" + socket.getPort());
				new Thread(new SocketThread(ServerFx.this, socket)).start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			Utils.closeQuietly(server);
		}
	}
}

// 作用：和每一个连接的客户端socket进行异步通信
class SocketThread implements Runnable {
	private ServerFx serverFx;
	public SocketThread(ServerFx main, Socket socket) {
		serverFx = main;
		this.socket = socket;
	}
	
	private DataInputStream in;
	private Socket socket;

	public void run() {
		// 开始通信
		try {
			in = new DataInputStream(
					new BufferedInputStream(socket.getInputStream()));

			while (true) {
				String message = in.readUTF();
				
				serverFx.appendMessage(message + "\n");
				// System.out.println(message);
				
				if ("88".equals(message)) {
					break;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			Utils.closeQuietly(in);
			Utils.closeQuietly(socket);
		}
	}
}
